using System;
using System.Collections.Generic;
using System.Data;
using System.Resources;
using PluginFrame;

namespace PcrExperimentProject
{
	[Serializable]
	public class PcrProgramStructure : IPcrProgram, ICloneable
	{
		[NonSerialized]
		protected IMiscService mMiscService;

		[NonSerialized]
		protected ResourceManager mResourceManager;

		[NonSerialized]
		protected IConfigurationService mConfigurationService;

		[NonSerialized]
		protected IApplication mApplication;

		protected IPcrExperimentProject mPcrExperimentProject;

		protected List<IAmplificationSegment> mAmplificationSegments;

		protected List<IMeltingSegment> mMeltingSegments;

		protected List<IMeltingSegment> mHRMSegments;

		protected int mAvailableAmplificationSegmentCount;

		protected PcrExperimentType mPcrExperimentType;

		protected int mAmplificationStepCount;

		protected int mAmplificationDetectionCount;

		protected int mMeltingDetectionCount;

		protected int mMeltingStepCount;

		protected string mProgramFileName;

		protected int mALLDetectionCount;

		protected int mTotalExperimentSecond;

		protected double mLastAmplificationTemperature;

		public double LastAmplificationTemperature
		{
			get
			{
				return mLastAmplificationTemperature;
			}
		}

		public IPcrExperimentProject PcrExperimentProject
		{
			get
			{
				return mPcrExperimentProject;
			}
			set
			{
				mPcrExperimentProject = value;
			}
		}

		public int TotalExperimentSecond
		{
			get
			{
				return mTotalExperimentSecond;
			}
		}

		public List<IMeltingSegment> MeltingSegments
		{
			get
			{
				return mMeltingSegments;
			}
		}

		public List<IMeltingSegment> HRMSegments
		{
			get
			{
				return mHRMSegments;
			}
		}

		public List<IAmplificationSegment> AmplificationSegments
		{
			get
			{
				return mAmplificationSegments;
			}
			set
			{
				mAmplificationSegments = value;
			}
		}

		public int AmplificationSegmentCount
		{
			get
			{
				return mAmplificationSegments.Count;
			}
		}

		public int AvailableAmplificationSegmentCount
		{
			get
			{
				return mAvailableAmplificationSegmentCount;
			}
		}

		public PcrExperimentType PcrExperimentType
		{
			get
			{
				return mPcrExperimentType;
			}
		}

		public int AmplificationStepCount
		{
			get
			{
				return mAmplificationStepCount;
			}
		}

		public int AmplificationDetectionCount
		{
			get
			{
				return mAmplificationDetectionCount;
			}
			set
			{
				mAmplificationDetectionCount = value;
			}
		}

		public int MeltingDetectionCount
		{
			get
			{
				return mMeltingDetectionCount;
			}
		}

		public int ALLDetectionCount
		{
			get
			{
				return mALLDetectionCount;
			}
			set
			{
				mALLDetectionCount = value;
			}
		}

		public int MeltingStepCount
		{
			get
			{
				return mMeltingStepCount;
			}
		}

		public object Clone()
		{
			return MemberwiseClone();
		}

		public bool HasAvailableMeltingSegment()
		{
			try
			{
				if (mMeltingDetectionCount > 0)
				{
					return true;
				}
				if (mMeltingSegments != null && mMeltingSegments.Count > 0 && mMeltingSegments[0].IsAvailable)
				{
					return true;
				}
				return false;
			}
			catch (Exception)
			{
				return false;
			}
		}

		public bool HasAvailableHRMSegment()
		{
			if (mMeltingDetectionCount > 0)
			{
				return true;
			}
			if (mHRMSegments != null && mHRMSegments.Count > 0 && mHRMSegments[0].IsAvailable)
			{
				return true;
			}
			return false;
		}

		public PcrProgramStructure(IApplication application, IPcrExperimentProject pcrExperimentProject)
		{
			mApplication = application;
			mPcrExperimentProject = pcrExperimentProject;
			mResourceManager = ResourceManager.CreateFileBasedResourceManager("PcrExperimentProject", application.GetResourceFolder() + GetType().Namespace + "\\", null);
			IConfigurationService configurationService = (IConfigurationService)application.GetService("ConfigurationService");
			mMiscService = (IMiscService)application.GetService("MiscService");
			mAmplificationSegments = new List<IAmplificationSegment>(configurationService.PcrProgramConfiguration.ProgramSegmentCount);
			for (int i = 0; i < mAmplificationSegments.Capacity; i++)
			{
				mAmplificationSegments.Add(new AmplificationSegment(mResourceManager.GetString("SegmentString") + " " + (i + 1), i + 1, this));
			}
			mAmplificationSegments[0].IsAvailable = true;
			mMeltingSegments = new List<IMeltingSegment>(1);
			mMeltingSegments.Add(new MeltingSegment(mAmplificationSegments.Capacity));
			mMeltingSegments[0].Name = mResourceManager.GetString("MeltingString");
			mHRMSegments = new List<IMeltingSegment>(1);
			mHRMSegments.Add(new HRMSegment(mAmplificationSegments.Capacity));
		}

		public PcrProgramStructure(string programFileName)
		{
			mProgramFileName = programFileName;
		}

		private int CalculateAmplificationSegmentTotalSecond(IAmplificationSegment segment, ref double lastTemperature)
		{
			if (mMiscService == null)
			{
				mMiscService = (IMiscService)mApplication.GetService("MiscService");
			}
			if (mConfigurationService == null)
			{
				mConfigurationService = (IConfigurationService)mApplication.GetService("ConfigurationService");
			}
			int num = 0;
			double result = 0.0;
			int num2 = 0;
			for (int i = 0; i < segment.Cycle; i++)
			{
				foreach (DataRow row in segment.StepTable.Rows)
				{
					if (!double.TryParse(row["Temperature"].ToString(), out result))
					{
						result = 0.0;
					}
					num2 = mMiscService.CovertTimeStringToSecond(row["HoldTime"].ToString());
					if (Convert.ToBoolean(row["Advanced"]))
					{
						double num3 = (Convert.ToBoolean(row["TemperatureVariation"]) ? 1 : (-1));
						double result2 = 0.0;
						double.TryParse(row["TemperatureValue"].ToString(), out result2);
						result += num3 * (double)i * result2;
						int num4 = (Convert.ToBoolean(row["TimeVariation"]) ? 1 : (-1));
						int num5 = mMiscService.CovertTimeStringToSecond(row["TimeValue"].ToString());
						num2 += num4 * i * num5;
						if (num2 < 0)
						{
							num2 = 0;
						}
					}
					double result3 = 0.0;
					double.TryParse(row["Rising/FallingRate"].ToString(), out result3);
					double num6;
					if (result > lastTemperature)
					{
						num6 = mConfigurationService.RunMeasuementConfiguration.MaxTemperatureUpRate;
						double upMeasureDelaySecond = mConfigurationService.RunMeasuementConfiguration.UpMeasureDelaySeconds;
					}
					else
					{
						num6 = mConfigurationService.RunMeasuementConfiguration.MaxTemperatureDownRate;
						double downMeasureDelaySecond = mConfigurationService.RunMeasuementConfiguration.DownMeasureDelaySeconds;
					}
					if (result3 <= 0.0)
					{
						result3 = num6;
					}
					num += num2 + (int)(Math.Abs(result - lastTemperature) / result3);
					lastTemperature = result;
				}
			}
			return num;
		}

		public int CalculateAmplificationSegmentSecond(int startSegment, int stopSegment, ref double lastTemperature)
		{
			int num = 0;
			for (int i = startSegment; i <= stopSegment; i++)
			{
				if (mAmplificationSegments[i].IsAvailable)
				{
					num += CalculateAmplificationSegmentTotalSecond(mAmplificationSegments[i], ref lastTemperature);
				}
			}
			return num;
		}

		public int CalculateMeltingSegmentSecond(int startCycle, int stopCycle, IMeltingSegment segment, ref double lastTemperature)
		{
			if (mPcrExperimentProject.SystemType == PcrSystemType.GeneScan)
			{
				IGeneScanPcrExperimentProject geneScanPcrExperimentProject = mPcrExperimentProject as IGeneScanPcrExperimentProject;
				if (geneScanPcrExperimentProject != null && geneScanPcrExperimentProject.HRMMode == HRMModeEnum.Continue)
				{
					return CalculateContinueHRMSegmentSecond(segment, geneScanPcrExperimentProject.SettingRate, ref lastTemperature);
				}
			}
			if (mMiscService == null)
			{
				mMiscService = (IMiscService)mApplication.GetService("MiscService");
			}
			if (mConfigurationService == null)
			{
				mConfigurationService = (IConfigurationService)mApplication.GetService("ConfigurationService");
			}
			int num = 0;
			double num2 = 0.0;
			int num3 = 0;
			for (int i = startCycle; i < stopCycle; i++)
			{
				num2 = segment.StartDegree + (double)i * segment.StepInterval;
				num3 = mMiscService.CovertTimeStringToSecond(segment.HoldTime);
				double num4 = segment.Rate;
				double num5;
				if (num2 > lastTemperature)
				{
					num5 = mConfigurationService.RunMeasuementConfiguration.MaxTemperatureUpRate;
					double upMeasureDelaySecond = mConfigurationService.RunMeasuementConfiguration.UpMeasureDelaySeconds;
				}
				else
				{
					num5 = mConfigurationService.RunMeasuementConfiguration.MaxTemperatureDownRate;
					double downMeasureDelaySecond = mConfigurationService.RunMeasuementConfiguration.DownMeasureDelaySeconds;
				}
				if (num4 <= 0.0)
				{
					num4 = num5;
				}
				num += num3 + (int)(Math.Abs(num2 - lastTemperature) / num4);
				if (i == startCycle && num2 == lastTemperature)
				{
					num += num3;
				}
				lastTemperature = num2;
			}
			return num;
		}

		private int CalculateContinueHRMSegmentSecond(IMeltingSegment segment, double rate, ref double lastTemperature)
		{
			int num = 0;
			double startDegree = segment.StartDegree;
			int num2 = mMiscService.CovertTimeStringToSecond(segment.HoldTime);
			double maxTemperatureUpRate = mConfigurationService.RunMeasuementConfiguration.MaxTemperatureUpRate;
			num += num2 + (int)(Math.Abs(startDegree - lastTemperature) / maxTemperatureUpRate);
			lastTemperature = startDegree;
			startDegree = segment.StopDegree;
			num += num2 + (int)(Math.Abs(startDegree - lastTemperature) / rate);
			lastTemperature = segment.StopDegree;
			return num;
		}

		private int CalculateTotalMeltingSecond(int startSegment, int stopSegment, ref double lastTemperature)
		{
			int num = 0;
			for (int i = startSegment; i <= stopSegment; i++)
			{
				if (mMeltingSegments[i].IsAvailable)
				{
					num += CalculateMeltingSegmentSecond(0, mMeltingSegments[i].Cycle, mMeltingSegments[i], ref lastTemperature);
				}
			}
			return num;
		}

		private int CalculateTotalHRMSecond(int startSegment, int stopSegment, ref double lastTemperature)
		{
			int num = 0;
			IGeneScanPcrExperimentProject geneScanPcrExperimentProject = mPcrExperimentProject as IGeneScanPcrExperimentProject;
			if (geneScanPcrExperimentProject != null)
			{
				for (int i = startSegment; i <= stopSegment; i++)
				{
					if (mHRMSegments[i].IsAvailable)
					{
						num += CalculateMeltingSegmentSecond(0, mHRMSegments[i].Cycle, mHRMSegments[i], ref lastTemperature);
					}
				}
			}
			return num;
		}

		public string GetExperimentTotalTime(bool isCalculateTotalTime)
		{
			if (mTotalExperimentSecond == 0 || isCalculateTotalTime)
			{
				double lastTemperature = 20.0;
				mTotalExperimentSecond = CalculateAmplificationSegmentSecond(0, mAmplificationSegments.Count - 1, ref lastTemperature) + CalculateTotalMeltingSecond(0, mMeltingSegments.Count - 1, ref lastTemperature) + CalculateTotalHRMSecond(0, mHRMSegments.Count - 1, ref lastTemperature);
			}
			return new DateTime((long)mTotalExperimentSecond * 10000000L).ToString("HH:mm:ss");
		}

		public IAmplificationSegment GetAmplificationSegment(int index)
		{
			return mAmplificationSegments[index];
		}

		public IMeltingSegment GetMeltingSegment(int index)
		{
			if (mMeltingSegments == null)
			{
				mMeltingSegments = new List<IMeltingSegment>(1);
				mMeltingSegments.Add(new MeltingSegment(mAmplificationSegments.Capacity));
				mMeltingSegments[0].Name = mResourceManager.GetString("MeltingString");
			}
			if (string.IsNullOrEmpty(mMeltingSegments[0].Name))
			{
				mMeltingSegments[0].Name = mResourceManager.GetString("MeltingString");
			}
			if (index >= 0 && index < mMeltingSegments.Count)
			{
				return mMeltingSegments[index];
			}
			return null;
		}

		public IMeltingSegment GetHRMSegment(int index)
		{
			if (mHRMSegments == null)
			{
				mHRMSegments = new List<IMeltingSegment>(1);
				mHRMSegments.Add(new HRMSegment(mAmplificationSegments.Capacity));
				mHRMSegments[0].Name = mResourceManager.GetString("HRMString");
			}
			if (string.IsNullOrEmpty(mHRMSegments[0].Name))
			{
				mHRMSegments[0].Name = mResourceManager.GetString("HRMString");
			}
			if (index >= 0 && index < mHRMSegments.Count)
			{
				return mHRMSegments[index];
			}
			return null;
		}

		public void SwapAmplificationSegment(int firstIndex, int secondIndex)
		{
			int index = firstIndex - 1;
			int index2 = secondIndex - 1;
			IAmplificationSegment value = mAmplificationSegments[index];
			mAmplificationSegments[index] = mAmplificationSegments[index2];
			mAmplificationSegments[index2] = value;
			mAmplificationSegments[index].Index = firstIndex;
			mAmplificationSegments[index2].Index = secondIndex;
		}

		public void SetApplication(IApplication app)
		{
			mApplication = app;
			mResourceManager = ResourceManager.CreateFileBasedResourceManager("PcrExperimentProject", mApplication.GetResourceFolder() + GetType().Namespace + "\\", null);
		}

		public IApplication GetApplication()
		{
			return mApplication;
		}

		public void Update()
		{
			mAmplificationDetectionCount = 0;
			mMeltingDetectionCount = 0;
			mAmplificationStepCount = 0;
			mMeltingStepCount = 0;
			mAvailableAmplificationSegmentCount = 0;
			mTotalExperimentSecond = 0;
			double lastTemperature = 20.0;
			bool flag = false;
			for (int i = 0; i < AmplificationSegmentCount; i++)
			{
				IAmplificationSegment amplificationSegment = GetAmplificationSegment(i);
				if (flag)
				{
					amplificationSegment.IsAvailable = false;
					continue;
				}
				int count = amplificationSegment.StepTable.Rows.Count;
				if (count <= 0)
				{
					amplificationSegment.IsAvailable = false;
				}
				if (amplificationSegment.IsAvailable)
				{
					mAvailableAmplificationSegmentCount++;
					mAmplificationStepCount += count * amplificationSegment.Cycle;
					mTotalExperimentSecond += CalculateAmplificationSegmentTotalSecond(amplificationSegment, ref lastTemperature);
					if (amplificationSegment.FluoscenceStep > 0)
					{
						mAmplificationDetectionCount += amplificationSegment.Cycle;
					}
				}
				else
				{
					flag = true;
				}
			}
			mLastAmplificationTemperature = lastTemperature;
			for (int j = 0; j < mMeltingSegments.Count; j++)
			{
				IMeltingSegment meltingSegment = GetMeltingSegment(j);
				if (meltingSegment.IsAvailable)
				{
					mMeltingStepCount += meltingSegment.CalculateMeltingCycle();
					mMeltingDetectionCount += mMeltingStepCount;
					mTotalExperimentSecond += CalculateMeltingSegmentSecond(0, meltingSegment.Cycle, meltingSegment, ref lastTemperature);
				}
			}
			if (mHRMSegments == null)
			{
				mHRMSegments = new List<IMeltingSegment>(1);
				mHRMSegments.Add(new HRMSegment(mAmplificationSegments.Capacity));
			}
			for (int k = 0; k < mHRMSegments.Count; k++)
			{
				IMeltingSegment hRMSegment = GetHRMSegment(k);
				if (!hRMSegment.IsAvailable)
				{
					continue;
				}
				IGeneScanPcrExperimentProject geneScanPcrExperimentProject = mPcrExperimentProject as IGeneScanPcrExperimentProject;
				if (geneScanPcrExperimentProject != null)
				{
					if (geneScanPcrExperimentProject.HRMMode == HRMModeEnum.Continue)
					{
						mMeltingStepCount += 2;
						mMeltingDetectionCount += 2;
						mTotalExperimentSecond += CalculateContinueHRMSegmentSecond(hRMSegment, geneScanPcrExperimentProject.SettingRate, ref lastTemperature);
					}
					else
					{
						mMeltingStepCount += hRMSegment.CalculateMeltingCycle();
						mMeltingDetectionCount += mMeltingStepCount;
						mTotalExperimentSecond += CalculateMeltingSegmentSecond(0, hRMSegment.Cycle, hRMSegment, ref lastTemperature);
					}
				}
			}
			mALLDetectionCount = mAmplificationDetectionCount + mMeltingDetectionCount;
			if (mAmplificationDetectionCount > 0 && mMeltingDetectionCount > 0)
			{
				mPcrExperimentType = PcrExperimentType.AmplificationMelting;
			}
			else if (mMeltingDetectionCount > 0)
			{
				mPcrExperimentType = PcrExperimentType.Melting;
			}
			else
			{
				mPcrExperimentType = PcrExperimentType.Amplification;
			}
		}

		public void RefreshHRMDetectionCount()
		{
			if (mHRMSegments == null)
			{
				mHRMSegments = new List<IMeltingSegment>(1);
				mHRMSegments.Add(new HRMSegment(mAmplificationSegments.Capacity));
			}
			for (int i = 0; i < mHRMSegments.Count; i++)
			{
				IMeltingSegment hRMSegment = GetHRMSegment(i);
				if (hRMSegment.IsAvailable)
				{
					mMeltingStepCount += hRMSegment.CalculateMeltingCycle();
					mMeltingDetectionCount += mMeltingStepCount;
				}
			}
		}

		public bool IsEqual(IPcrProgram pcrProgram)
		{
			if (mAvailableAmplificationSegmentCount != pcrProgram.AvailableAmplificationSegmentCount)
			{
				return false;
			}
			if (mPcrExperimentType != pcrProgram.PcrExperimentType)
			{
				return false;
			}
			if (mAmplificationStepCount != pcrProgram.AmplificationStepCount)
			{
				return false;
			}
			if (mAmplificationDetectionCount != pcrProgram.AmplificationDetectionCount)
			{
				return false;
			}
			if (mMeltingDetectionCount != pcrProgram.MeltingDetectionCount)
			{
				return false;
			}
			if (mMeltingStepCount != pcrProgram.MeltingStepCount)
			{
				return false;
			}
			if (mALLDetectionCount != pcrProgram.ALLDetectionCount)
			{
				return false;
			}
			int mTotalExperimentSecond2 = mTotalExperimentSecond;
			int totalExperimentSecond = pcrProgram.TotalExperimentSecond;
			for (int i = 0; i < AmplificationSegments.Count; i++)
			{
				if (!mAmplificationSegments[i].IsEqual(pcrProgram.AmplificationSegments[i]))
				{
					return false;
				}
			}
			for (int j = 0; j < mMeltingSegments.Count; j++)
			{
				if (!mMeltingSegments[j].IsEqual(pcrProgram.MeltingSegments[j]))
				{
					return false;
				}
			}
			if (mHRMSegments != null && pcrProgram.HRMSegments != null)
			{
				for (int k = 0; k < mHRMSegments.Count; k++)
				{
					if (!mHRMSegments[k].IsEqual(pcrProgram.HRMSegments[k]))
					{
						return false;
					}
				}
			}
			return true;
		}
	}
}
